package com.xdan.memory.listener;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xdan.memory.config.RobotConfig;
import com.xdan.memory.entity.MonitoringModelVo;
import com.xdan.memory.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author:
 * @since: 2023/9/7 13:39
 **/

@Slf4j
@Service
public class ListenerService {

    @Resource
    private RobotConfig robotConf;


    //    @Scheduled(fixedDelay = 1000 * 60)
    public void listener() {
        String errorInfo = RedisUtil.getStr(robotConf.getChatId());
        if (!StringUtils.isEmpty(errorInfo) && "true".equals(errorInfo)) {
            log.info("已经在redis中");
            return;
        }
        String response = HttpRequest.post(robotConf.getModelUrl()).execute().body();
        log.info("model数据{}", response);
        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (jsonObject.isEmpty()) {
            return;
        }
        JSONArray jsonArray = jsonObject.getJSONArray("data");
        if (jsonArray.isEmpty()) {
            return;
        }
        List<MonitoringModelVo> monitoringModelVos = JSONUtil.toList(jsonArray, MonitoringModelVo.class);
        listenerModel(monitoringModelVos);
    }

    public void listenerModel(List<MonitoringModelVo> monitoringModelVos) {
        for (MonitoringModelVo m : monitoringModelVos) {
            if (StringUtils.isEmpty(m.getModelName()) || StringUtils.isEmpty(m.getBaseModelName())) {
                String message = buildEmptyMessage(m);
                log.error(message);
                continue;
            }

            String url = "https://www.xdan.ai/api/i/5b20817aa4b657835db7519bd99e2ef5/chat";
            log.info("请求{}, {}", m.getModelName(), m.getModelUrl());
            try {
                String body = "{\"model\":\"{model}\",\"messages\":[{\"role\":\"user\",\"content\":\"你好\"}],\"max_tokens\":1000,\"temperature\":0.9}";
                body = body.replace("{model}", StringUtils.isEmpty(m.getBaseModel()) ? m.getModelName() :m.getBaseModel());
                log.info("请求body{}", body);
                String response = HttpRequest.post(url).header("Authorization", "Bearer xdan-36c3d738b5a6bd4023947386a3cdc1e0").timeout(120000).body(body).execute().body();
                log.info("模型返回{}", response);
                if (response.isEmpty()) {
                    throw new RuntimeException("无返回数据");
                }

                if (response.contains("Time-out")) {
                    throw new RuntimeException("超时");
                }
                if (response.contains("code") && response.contains("500")) {
                    throw new RuntimeException(response);
                }
                if (response.contains("{\"detail\":")) {
                    throw new RuntimeException(response);
                }
            } catch (Exception e) {
                log.error(m.getModelName() + "模型监控异常\\n{}\\n{}",processingErrorMessage(e.getMessage()), buildMessage(m));
            }
        }

    }

    private String buildEmptyMessage(MonitoringModelVo m) {
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isEmpty(m.getModelName())) {
            sb.append("未指定模型").append(buildMessage(m));
        }
        if (StringUtils.isEmpty(m.getBaseModelName())) {
            sb.append("未指定基座").append(buildMessage(m));
        }
        return sb.toString();
    }

    private String buildMessage(MonitoringModelVo m) {
        StringBuilder sb = new StringBuilder();
        sb.append("\\n").append("模型名:").append(StringUtils.isEmpty(m.getBaseModel()) ? m.getModelName() :m.getBaseModel()).append("\\n")
                .append("url:").append(StringUtils.isEmpty(m.getBaseUrl()) ? m.getModelUrl() : m.getBaseUrl()).append("\\n")
                .append("基座:").append(m.getBaseModelName()).append("\\n")
                .append("受影响的agent:").append("\\n")
                .append(m.getAgents().stream().map(a -> "AgentName:" + a.getName() + "   " + "AgentId:" + a.getAsstId()).reduce((a, b) -> a + "\\n" + b).orElse("无"));
        return sb.toString();
    }


    public static String processingErrorMessage(String message) {
        message = JSONUtil.quote(message);
        if (message != null && message.length() > 2 && message.startsWith("\"") && message.endsWith("\"")) {
            return message.substring(1, message.length() - 1);
        }
        return message;
    }

//    public void listenerModel(String name, String url) {
//        url = "https://www.xdan.ai/api/i/5b20817aa4b657835db7519bd99e2ef5/chat";
//        log.info("请求{}, {}", name, url);
//        String errorInfo = RedisUtil.getStr(robotConf.getChatId());
//        if (!StringUtils.isEmpty(errorInfo) && "true".equals(errorInfo)) {
//            log.info("已经在redis中");
//            return;
//        }
//
//        try {
////            String body = "{\"model\":\"{model}\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}],\"max_tokens\":1000,\"temperature\":0.9}";
//            String body = "{\"model\":\"{model}\",\"messages\":[{\"role\":\"user\",\"content\":\"你好\"}],\"max_tokens\":1000,\"temperature\":0.9,\"conversationId\":\"1\"}";
//            body = body.replace("{model}", name);
//            String response = HttpRequest.post(url).header("Authorization", "Bearer xdan-36c3d738b5a6bd4023947386a3cdc1e0").timeout(120000).body(body).execute().body();
//            log.info("模型返回{}", response);
//            if (response.isEmpty()) {
//                throw new RuntimeException("无返回数据");
//            }
//            if (response.contains("Time-out")) {
//                throw new RuntimeException("超时");
//            }
//            if (response.contains("code") && response.contains("500")) {
//                throw new RuntimeException(response);
//            }
//            if (response.contains("{\"detail\":")) {
//                throw new RuntimeException(response);
//            }
//        } catch (Exception e) {
//            log.error(name + "模型监控异常{}\\n",processingErrorMessage(e.getMessage()));
//        }
//    }
}